﻿using GalaSoft.MvvmLight;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ALiteTeam.PackageTracer.Core;
using ALiteTeam.PackageTracer.Core.Impl;
using GalaSoft.MvvmLight.Command;
using System.Windows.Threading;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;

namespace ALiteTeam.PackageTracer.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class MainPageViewModel : ViewModelBase
    {
        public IDeliveryOperate DeliveryOp { get; set; }
        public IOrderOperate OrderOp{get;set;}
        public ILogWrite LogWriter { get; set; }

        public static readonly Guid ON_NAVIGATED_TO = Guid.NewGuid();

        private bool _IsFirstLoad = true;

        /// <summary>
        /// Initializes a new instance of the MainPagesViewModel class.
        /// </summary>
        public MainPageViewModel()
        {
            if (IsInDesignMode)
            {
                // Code runs in Blend --> create design time data.
            }
            else
            {
                this.DeliveryOp = DeliveryDataOp.Instance;
                this.LogWriter = new GeneralLogWriter();
                this.OrderOp = new OrderOp();

                this.LoadPriorityDeliveries();
                this.LoadDeliveryOrders();

                this.LoadDeliveryOrdersCommand = new RelayCommand(LoadDeliveryOrders);
                this.NavigationToSelectorCommand = new RelayCommand(NavigationToSelector);
                this.BackKeyPressCommand = new RelayCommand<System.ComponentModel.CancelEventArgs>(BackKeyPress);

                Messenger.Default.Register<NotificationMessage<NavigationEventArgs>>(this, ON_NAVIGATED_TO, OnNavigatedTo);
            }
        }

        private void LoadPriorityDeliveries()
        {
            var deliveries = this.DeliveryOp.GetPriorityDeliveries(10);

            var priorityDeliveries = deliveries.Select(e=> new  PriorityDelivery(e));
            PriorityDeliveries = new ObservableCollection<PriorityDelivery>(priorityDeliveries);
        }

        public RelayCommand LoadDeliveryOrdersCommand { get; private set; }
        private void LoadDeliveryOrders()
        {
            var lst = this.OrderOp.GetAll();
            var orders = lst.Select(e => new DeliveryOrderSubViewModel(e));
            this.DeliveryOrders = new ObservableCollection<DeliveryOrderSubViewModel>(orders);            
        }

        public RelayCommand NavigationToSelectorCommand { get; private set; }
        private void NavigationToSelector()
        {
            (Application.Current.RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame).Navigate(new Uri("/View/Selector.xaml", UriKind.Relative));
        }

        public RelayCommand<System.ComponentModel.CancelEventArgs> BackKeyPressCommand { get; private set; }
        public void BackKeyPress(System.ComponentModel.CancelEventArgs args)
        {
            //if (MessageBox.Show("是否确认退出？", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            //{
            //    args.Cancel = false;
            //}
            //else
            //{
            //    args.Cancel = true;
            //}
        }

        public void OnNavigatedTo(NotificationMessage<NavigationEventArgs> message)
        {
            NavigationEventArgs e = message.Content;

            // 仅在第一次访问时执行
            if (_IsFirstLoad == true)
            {
                // 清除异常堆栈
                Settings.AppContext.ExceptionStack.Clear();

                // 清除App Tile上的数字
                Settings.Configuration.UpdateOrder.Clear();
                ALiteTeam.PackageTracer.Core.TileHandlerForAgent.ResetDefaultTile(Settings.Configuration.UpdateOrder.Count);

                _IsFirstLoad = false;
            }

            // 移除所有向前翻页操作，使按向前键会直接退出程序
            while ((Application.Current.RootVisual as PhoneApplicationFrame).BackStack.Count() > 0)
            {
                (Application.Current.RootVisual as PhoneApplicationFrame).RemoveBackEntry();
            }

            // 如果不是返回模式，则需要判断加载到哪一页
            if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
            {
                // URI参数优先级最高，只要参数存在，则以参数指定为准
                if (string.IsNullOrEmpty(message.Notification) == false)
                {
                    this.PivotSelectedIndex = int.Parse(message.Notification);
                }
                // 否则判断是否存在运单，若存在则进入列表页，否则进入快递选择页
                else if (this.DeliveryOrders.Count > 0)
                {
                    this.PivotSelectedIndex = 1;
                }
                else
                {
                    this.PivotSelectedIndex = 0;
                }
            }
        }

        #region 绑定属性
        /// <summary>
        /// The <see cref="PivotSelectedIndex" /> property's name.
        /// </summary>
        public const string PivotSelectedIndexPropertyName = "PivotSelectedIndex";
        private int mPivotSelectedIndex = 0;

        /// <summary>
        /// Gets the PivotSelectedIndex property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public int PivotSelectedIndex
        {
            get
            {
                return mPivotSelectedIndex;
            }

            set
            {
                if (mPivotSelectedIndex == value)
                {
                    return;
                }

                mPivotSelectedIndex = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(PriorityDeliveriesPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="PriorityDeliveries" /> property's name.
        /// </summary>
        public const string PriorityDeliveriesPropertyName = "PriorityDeliveries";
        private ObservableCollection<PriorityDelivery> mPriorityDeliveries = new ObservableCollection<PriorityDelivery>();

        /// <summary>
        /// Gets the PriorityDeliveries property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<PriorityDelivery> PriorityDeliveries
        {
            get
            {
                return mPriorityDeliveries;
            }

            set
            {
                if (mPriorityDeliveries == value)
                {
                    return;
                }

                mPriorityDeliveries = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(PriorityDeliveriesPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="DeliveryOrders" /> property's name.
        /// </summary>
        public const string DeliveryOrdersPropertyName = "DeliveryOrders";

        private ObservableCollection<DeliveryOrderSubViewModel> mDeliveryOrders = new ObservableCollection<DeliveryOrderSubViewModel>();

        /// <summary>
        /// Gets the DeliveryOrders property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<DeliveryOrderSubViewModel> DeliveryOrders
        {
            get
            {
                return mDeliveryOrders;
            }
            set
            {
                if (mDeliveryOrders == value)
                {
                    return;
                }
                mDeliveryOrders = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(DeliveryOrdersPropertyName);
            }
        }
        #endregion
    }
}